﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using log4net;

namespace Logistics.Print
{
    public class DynamicExpress
    {
        private static ILog Log = LogManager.GetLogger(typeof(DynamicExpress).FullName);

        public String Express { get; private set; }
        public Hashtable Context { get; private set; }

        public DynamicExpress(String Express,Hashtable Context)
        {
            if (String.IsNullOrWhiteSpace(Express) || Context==null)
                throw new ArgumentNullException();
            this.Express = Express;
            this.Context = Context;
        }

        public String Eval()
        {
            // {$.abc,format=F2}
            Log.Debug("开始解析表达式:" + this.Express);
            ExpressObject expObj = new ExpressObject(this.Express);
            Object obj = this.Context[expObj.VarName.Trim().ToLower()];
            String value = "" ;
            if(obj!=null)
            {
                value = obj.ToString();
                if (!String.IsNullOrWhiteSpace(expObj.Format))
                {
                    value = String.Format("{0:" + expObj.Format + "}", obj);
                }
            }
            Log.Debug(this.Express + "=" + value);
            return value;
        }

        public class ExpressObject
        {
            public String VarName { get; set; }
            public String Format { get; set; }

            /// <summary>
            /// 
            /// </summary>
            /// <param name="exp"></param>
            public ExpressObject(String exp)
            {
                this.VarName = "";
                this.Format = "";
                Parse(exp);
            }

            private void Parse(String exp)
            {
                // {$.abc,format=F2}
                if (String.IsNullOrWhiteSpace(exp))
                    return ;
                exp = exp.Trim();
                if (!(exp.StartsWith("{") && exp.EndsWith("}")) || exp.Length <= 4)
                    return;
                exp = exp.Substring(1,exp.Length-2);//去掉{}

                String[] parts = exp.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (String part in parts)
                {
                    String seg = part.Trim();
                    if (seg.StartsWith("$."))
                    {
                        String name = seg.Substring(2);
                        this.VarName = name;
                        continue;
                    }
                    if (seg.Contains("="))//format=F2
                    {
                        String[] keyval = seg.Split(new String[]{"="},StringSplitOptions.RemoveEmptyEntries);
                        if (keyval != null && keyval.Length == 2)
                        {
                            keyval[0] = keyval[0].Trim();
                            keyval[1] = keyval[1].Trim();
                            if (String.Compare("format", keyval[0], true) == 0)
                            {
                                this.Format = keyval[1];
                            }
                        }
                    }
                }
            }
        }
    }
}
